Coding Style

We tried hard to make coding with swing-ui as easy and intuitive as possible, and we are proud of what we achieved, even though some workarounds had to be done.

Check out these most important things to keep in mind to help you get comfortable and find your way around easily.

1. ECMAScript Standard

This module follows the ECMAScript Module (ESM) standard. It uses import/export syntax and must be loaded in projects that support ESM. CommonJS (require, module.exports) is not supported.

To use this module, your package.json must include:

{
  "type": "module"
}

Your project code must also use ECMAScript module syntax.

2. Importing the Module

The module needs to be imported into the project only once in the beginning of your main JavaScript file.

import "swing-ui";

This imports all classes and global function that come with the module.

3. Creating First Window

Even though creating a Window component using new Window() notation is possible, it's not a recommended way.

A more preferred way is to extend Window component into your own custom class like this:

class LoginWindow extends Window
{
	// your custom class properties
	
	constructor()
	{
		super("Please Log In");
		
		// your code
		this.show().position(200, 200).size(600, 400).closeOperation(Window.CloseOperation.Exit);
		
		this.firstButton = new Button("Click Me").addTo(this).position(15, 15).size(100, 30);
	}
	
	// more methods
}

// now create an instance of the custom class and create a global reference to it
globalThis.mainForm = new AppDepot();

4. Importing Another Class

Most likely your application will grow and not stay in one file, so you will have to create a new JavaScript file for each window, and for custom UI components that extend Panel class.

You create a new file, for example dialog-window.js, in your project directory, such as:

export class MyDialogWindow extends Window
{
	constructor(ownerWindow)
	{
		super("Wrong Password", ownerWindow);
		
		this.initUI();
	}
	
	initUI()
	{
		this.size(300, 200).show().closeOperation(Window.CloseOperation.Dispose);
		
		// more UI code
	}
}

Now in main window we can dynamically import the new dialog window class and create and instance from it like this:

class LoginWindow extends Window
{
	// ... other code
	async openCustomDialogWindow()
	{
		// more clean method
		const {MyDialogWindow} = await import("./dialog-window.js"); // "await" is required
		this.dialogWindow = new MyDialogWindow(this);
		
		// single line method
		this.dialogWindow = new (await import("./dialog-window.js")).MyDialogWindow(this); // "await" is required
	}
}

Notice that the only reason we passed this to a new dialog Window constructor is to set a window owner window. This way the dialog window will become modal (will stay over main window until it's closed). In other cases it may not be needed.

Another static way to import UI class from its file is at the top of the main script file, and then create an object of that class somewhere in the code:

const {MyDialogWindow} = await import("./dialog-window.js"); // "await" is required to wait until swing-ui module with all UI components load. Otherwise UI components (like Window) may be undefined in the new dialog class.

class LoginWindow extends Window
{
	// ... other code
	openCustomDialogWindow()
	{
		this.dialogWindow = new MyDialogWindow(this);
	}
}

5. Garbage Collection

The garbage collection in swing-ui module works so good that everything that gets lost ends up in garbage. Let me explain.

In the example above we stored a reference to the new class into a global variable because if the reference to that object is not stored in any variable, eventually garbage collection destroys that object (in JavaScript and in user interface).

So it's important to keep in mind to store references to your components. In the example above you can see that when a new button is created, the reference to the button is stored into this.firstButton property of the window object. That way it's also easy to reference from anywhere like this globalThis.mainForm.firstButton.text("New Text");, or from within the window object like this this.firstButton.text("New Text");.

If you want to free up memory taken by GUI components faster, you can call .destroy() method to destroy only that component, or .destroy(true) to recursively destroy that component and all components added to it.

6. Interacting with UI Components

All UI components have methods, such as .text(), that can be called to set and get the needed property value. When you provide the value parameter to the method, then you are setting a value, otherwise the value will be returned to you by that method.

Here is an example of setting and getting text to and from a text field:

let textField = new TextField("Initial text").addTo(parentWindow);

// Getting text of the component
alert(textField.text());

// setting new text to the component
textField.text("New text");

// now new text will be displayed in a dialog box
alert(textField.text());

Same applies to most component methods such as position(), size(), etc.

Some methods are only getters. You use them as object property, not a method/function. Some examples of such getters are id, parent, and components:

// check if a panel is a parent of a button
if(panel === button.parent) alert("Its a parent");

// Getting an array of child components of a container component
let _children = window.components;

// reading ID of child components
for(child of _children) alert(child.id);

Check each method's documentation to ensure you are using it correctly.

7. Method Chaining

If you noticed in examples above, sometimes we called multiple component methods in a row, one following another. You can do it with methods that return that same component to make this quick and short code writing possible. Most UI component methods in swing-ui module, when used as setters, return that component back to allow this method chaining technique.

Example:

textField.text("New Text").addTo(this).size(25, 150).position(30, 45);

8. Visual UI Designer

Don't worry if it looks like it takes a lot of code to create and set up all the components. We have built a visual GUI designer application to be able to build your forms and custom UI components the modern way by simply dragging and dropping components.

Check out our FREE Swing-UI GUI Designer app that makes your life even easier by helping you build UI much faster and completely without code, like in Microsoft Visual Studio.

Anything Else?

We think the rest should be easy and fun, but if we missed something, please let us know.